<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.6.3" />
<title>Prolog Facts for Gerrit Changes</title>
<style type="text/css">
/* Sans-serif font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
div#toctitle,
span#author, span#revnumber, span#revdate, span#revremark,
div#footer {
  font-family: Arial,Helvetica,sans-serif;
}

/* Serif font. */
div.sectionbody {
  font-family: Georgia,"Times New Roman",Times,serif;
}

/* Monospace font. */
tt {
  font-size: inherit;
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  font-size: inherit;
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}
ul > li     { color: #aaa; }
ul > li > * { color: black; }

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
}

div#footer {
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid #dddddd;
  border-left: 4px solid #f0f0f0;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid #dddddd;
  border-left: 5px solid #f0f0f0;
  background: #f8f8f8;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #f0f0f0;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > pre.content {
  font-family: inherit;
  font-size: inherit;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-weight: bold;
  color: #527bbd;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}

div.colist td {
  padding-right: 0.5em;
  padding-bottom: 0.3em;
  vertical-align: top;
}
div.colist td img {
  margin-top: 0.3em;
}

@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}

</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>Prolog Facts for Gerrit Changes</h1>
<span id="revnumber">version 2.5</span>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Prior to invoking the <tt>submit_rule(X)</tt> query for a change, Gerrit initializes
the Prolog engine with a set of facts (current data) about this change.
The following table provides an overview of the provided facts.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Important</div>
</td>
<td class="content">All the terms listed below are defined in the <tt>gerrit</tt> package. To use any
of them we must use a qualified name like <tt>gerrit:change_branch(X)</tt>.</td>
</tr></table>
</div>
<div class="tableblock">
<table rules="cols"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Table 1. Prolog facts about the current change</caption>
<col width="33%" />
<col width="33%" />
<col width="33%" />
<thead>
<tr>
<th align="left" valign="top">Fact                 </th>
<th align="left" valign="top">Example  </th>
<th align="left" valign="top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table"><tt>change_branch/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>change_branch('refs/heads/master').</tt></p></td>
<td align="left" valign="top"><p class="table">Destination Branch for the change as string atom</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>change_owner/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>change_owner(user(1000000)).</tt></p></td>
<td align="left" valign="top"><p class="table">Owner of the change as <tt>user(ID)</tt> term. ID is the numeric account ID</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>change_project/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>change_project('full/project/name').</tt></p></td>
<td align="left" valign="top"><p class="table">Name of the project as string atom</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>change_topic/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>change_topic('plugins').</tt></p></td>
<td align="left" valign="top"><p class="table">Topic name as string atom</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_author/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_author(user(100000)).</tt></p></td>
<td align="left" valign="top"><p class="table">Author of the commit as <tt>user(ID)</tt> term. ID is the numeric account ID</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_author/3</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_author(user(100000), 'John Doe', 'john.doe@example.com').</tt></p></td>
<td align="left" valign="top"><p class="table">ID, full name and the email of the commit author.  The full name and the
    email are string atoms</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_committer/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_committer()</tt></p></td>
<td align="left" valign="top"><p class="table">Committer of the commit as <tt>user(ID)</tt> term. ID is the numeric account ID</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_committer/3</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_committer()</tt></p></td>
<td align="left" valign="top"><p class="table">ID, full name and the email of the commit committer. The full name and the
    email are string atoms</p></td>
</tr>
<tr>
<td rowspan="2" align="left" valign="top"><p class="table"><tt>commit_label/2</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_label(label('Code-Review', 2), user(1000000)).</tt></p></td>
<td rowspan="2" align="left" valign="top"><p class="table">Set of votes on the last patch-set</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_label(label('Verified', -1), user(1000001)).</tt></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_message/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_message('Fix bug X').</tt></p></td>
<td align="left" valign="top"><p class="table">Commit message as string atom</p></td>
</tr>
<tr>
<td rowspan="4" align="left" valign="top"><p class="table"><tt>current_user/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>current_user(user(1000000)).</tt></p></td>
<td rowspan="4" align="left" valign="top"><p class="table">Current user as one of the four given possibilities</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>current_user(user(anonymous)).</tt></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>current_user(user(peer_daemon)).</tt></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>current_user(user(replication)).</tt></p></td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph"><p>In addition Gerrit provides a set of built-in helper predicates that can be used
when implementing the <tt>submit_rule</tt> predicate. The most common ones are listed in
the following table.</p></div>
<div class="tableblock">
<table rules="cols"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Table 2. Built-in Prolog helper predicates</caption>
<col width="33%" />
<col width="33%" />
<col width="33%" />
<thead>
<tr>
<th align="left" valign="top">Predicate                  </th>
<th align="left" valign="top">Example usage  </th>
<th align="left" valign="top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_delta/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_delta('\\.java$').</tt></p></td>
<td align="left" valign="top"><p class="table">True if any file name from the last patch set matches the given regex.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_delta/3</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_delta('\\.java$', T, P)</tt></p></td>
<td align="left" valign="top"><p class="table">Returns the change type (via <tt>T</tt>) and path (via <tt>P</tt>), if the change type
    is <tt>rename</tt>, it also returns the old path. If the change type is <tt>rename</tt>, it
    returns a delete for old path and an add for new path. If the change type
    is <tt>copy</tt>, an add is returned along with new path.</p>
<p class="table">    Possible values for the change type are the following symbols: <tt>add</tt>,
    <tt>modify</tt>, <tt>delete</tt>, <tt>rename</tt>, <tt>copy</tt></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_delta/4</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_delta('\\.java$', T, P, O)</tt></p></td>
<td align="left" valign="top"><p class="table">Like <tt>commit_delta/3</tt> plus the old path (via <tt>O</tt>) if applicable.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_edits/2</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_edits('/pom.xml$', 'dependency')</tt></p></td>
<td align="left" valign="top"><p class="table">True if any of the files matched by the file name regex (first parameter)
    have edited lines that match the regex in the second parameter. This
    example will be true if there is a modification of a <tt>pom.xml</tt> file such
    that an edited line contains or contained the string <tt>'dependency'</tt>.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>commit_message_matches/1</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>commit_message_matches('^Bug fix')</tt></p></td>
<td align="left" valign="top"><p class="table">True if the commit message matches the given regex.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">for a complete list of built-in helpers read the <tt>gerrit_common.pl</tt> and
all Java classes whose name matches <tt>PRED_*.java</tt> from Gerrit&#8217;s source code.</td>
</tr></table>
</div>
</div>
</div>
<hr style="
  height: 2px;
  color: silver;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
">
<div class="paragraph"><p>Part of <a href="index.html">Gerrit Code Review</a></p></div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Version 2.5<br />
Last updated 2012-10-31 19:34:02 CET
</div>
</div>
</body>
</html>
